package com.ethink.warehouse.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ethink.framework.common.db.PageUtils;
import com.ethink.framework.common.exception.BusinessException;
import com.ethink.id.generator.IdGenerator;
import com.ethink.warehouse.api.constant.WarehouseRespCode;
import com.ethink.warehouse.api.enums.MateInventoryCxLogOrderStatusEnum;
import com.ethink.warehouse.api.info.MateInventoryCxLogInfo;
import com.ethink.warehouse.api.info.MateInventoryCxLogModeInfo;
import com.ethink.warehouse.api.request.*;
import com.ethink.warehouse.api.response.MateInventoryCxLogAddResponse;
import com.ethink.warehouse.api.response.MateInventoryCxLogGetDetailResponse;
import com.ethink.warehouse.api.response.MateInventoryCxLogQueryResponse;
import com.ethink.warehouse.common.entity.MateInventoryCxDetailLog;
import com.ethink.warehouse.common.entity.MateInventoryCxLog;
import com.ethink.warehouse.common.mapper.MateInventoryCxDetailLogMapper;
import com.ethink.warehouse.common.mapper.MateInventoryCxLogMapper;
import com.ethink.warehouse.converter.MateInventoryCxLogConverter;
import com.ethink.warehouse.manager.MateInventoryManager;
import com.ethink.warehouse.service.MateInventoryCxLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Map;

/**
 * 库存拆卸记录 Service接口实现
 *
 * @author default
 * @date 2022-12-07
 */
@Slf4j
@Service
public class MateInventoryCxLogServiceImpl implements MateInventoryCxLogService {

    @Autowired
    private MateInventoryCxLogMapper mateInventoryCxLogMapper;

    @Autowired
    private MateInventoryCxDetailLogMapper mateInventoryCxDetailLogMapper;

    @Autowired
    private IdGenerator idGenerator;

    @Autowired
    private MateInventoryManager mateInventoryManager;

    @Autowired
    private MateInventoryCxLogConverter mateInventoryCxLogConverter;

    @Override
    public Page<MateInventoryCxLogQueryResponse> queryMateInventoryCxLog(MateInventoryCxLogQueryRequest request) {
        return mateInventoryCxLogMapper.queryMateInventoryCxLog(PageUtils.buildPage(request), request);
    }

    @Override
    public MateInventoryCxLogGetDetailResponse getMateInventoryCxLogById(Long mateInventoryCxLogId) {
        MateInventoryCxLogGetDetailResponse response = new MateInventoryCxLogGetDetailResponse();
        MateInventoryCxLogInfo mateInventoryCxLogInfo = mateInventoryCxLogMapper.getMateInventoryCxLogById(mateInventoryCxLogId);
        response.setMateInventoryCxLogInfo(mateInventoryCxLogInfo);
        response.setMateInventoryCxDetailLogInfoList(mateInventoryCxDetailLogMapper.listMateInventoryCxDetailLogByOrderNo(mateInventoryCxLogInfo.getOrderNo()));
        return response;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public MateInventoryCxLogAddResponse addMateInventoryCxLog(MateInventoryCxLogAddRequest request) {
        MateInventoryCxLogAddResponse response = new MateInventoryCxLogAddResponse();
        MateInventoryCxLog mateInventoryCxLog = new MateInventoryCxLog();
        BeanUtils.copyProperties(request, mateInventoryCxLog);
        String orderNo = idGenerator.chai();
        mateInventoryCxLog.setOrderNo(orderNo);
        mateInventoryCxLog.setOrderStatus(MateInventoryCxLogOrderStatusEnum.S1.getIntValue());
        mateInventoryCxLogMapper.insert(mateInventoryCxLog);
        request.getItems().forEach(item -> {
            MateInventoryCxDetailLog detailEntity = new MateInventoryCxDetailLog();
            detailEntity.setOrderNo(orderNo);
            detailEntity.setBeforeMateInventoryId(item.getBeforeMateInventoryId());
            detailEntity.setAfterMateSku(item.getAfterMateSku());
            detailEntity.setAfterMateSkuName(item.getAfterMateSkuName());
            detailEntity.setBeforeQty(item.getBeforeQty());
            detailEntity.setChaiQty(request.getChaiQty());
            mateInventoryCxDetailLogMapper.insert(detailEntity);
        });
        response.setId(mateInventoryCxLog.getId());
        return response;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateMateInventoryCxLog(MateInventoryCxLogUpdateRequest request) {
        MateInventoryCxLogInfo mateInventoryCxLogInfo = mateInventoryCxLogMapper.getMateInventoryCxLogById(request.getId());
        if (!mateInventoryCxLogInfo.getOrderStatus().equals(MateInventoryCxLogOrderStatusEnum.S1.getIntValue())) {
            throw new BusinessException(WarehouseRespCode.MATE_INVENTORY_CX_LOG_UPDATE_STATUS_ERR);
        }

        LambdaUpdateWrapper<MateInventoryCxLog> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(MateInventoryCxLog::getId, request.getId());
        updateWrapper.set(MateInventoryCxLog::getSubWarehouseCode, request.getSubWarehouseCode());
        updateWrapper.set(MateInventoryCxLog::getSubWarehouseName, request.getSubWarehouseName());
        updateWrapper.set(MateInventoryCxLog::getChaiQty, request.getChaiQty());
        updateWrapper.set(MateInventoryCxLog::getRemark, request.getRemark());
        mateInventoryCxLogMapper.update(null, updateWrapper);
        // 根据主表流水号，删除历史数据，然后新增
        // 明细数据删除
        LambdaQueryWrapper<MateInventoryCxDetailLog> detailQueryWrapper = new LambdaQueryWrapper<>();
        detailQueryWrapper.eq(MateInventoryCxDetailLog::getOrderNo, mateInventoryCxLogInfo.getOrderNo());
        mateInventoryCxDetailLogMapper.delete(detailQueryWrapper);
        // 明细数据新增
        request.getItems().forEach(item -> {
            MateInventoryCxDetailLog detailEntity = new MateInventoryCxDetailLog();
            detailEntity.setOrderNo(mateInventoryCxLogInfo.getOrderNo());
            detailEntity.setBeforeMateInventoryId(item.getBeforeMateInventoryId());
            detailEntity.setAfterMateSku(item.getAfterMateSku());
            detailEntity.setAfterMateSkuName(item.getAfterMateSkuName());
            detailEntity.setBeforeQty(item.getBeforeQty());
            detailEntity.setChaiQty(request.getChaiQty());
            mateInventoryCxDetailLogMapper.insert(detailEntity);
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void approvedMateInventoryCxLog(MateInventoryCxLogApprovedRequest request) {
        MateInventoryCxLog mateInventoryCxLog = mateInventoryCxLogMapper.selectById(request.getId());
        if (mateInventoryCxLog.getOrderStatus().equals(MateInventoryCxLogOrderStatusEnum.S2.getIntValue())) {
            throw new BusinessException(WarehouseRespCode.MATE_INVENTORY_CX_LOG_APPROVED_STATUS_ERR);
        }
        LambdaUpdateWrapper<MateInventoryCxLog> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(MateInventoryCxLog::getId, request.getId());
        updateWrapper.set(MateInventoryCxLog::getOrderStatus, MateInventoryCxLogOrderStatusEnum.S2.getIntValue());
        mateInventoryCxLogMapper.update(null, updateWrapper);
        // 明细数据
        // 库存变动
        Map<Long, Long> detailLogAfterMateInventoryIdMap = mateInventoryManager.cxMateInventory(
                mateInventoryCxLog,
                mateInventoryCxDetailLogMapper.listMateInventoryCxDetailLogByOrderNo(mateInventoryCxLog.getOrderNo()));
        // 更新调整后库存ID
        detailLogAfterMateInventoryIdMap.forEach((detailLogId, afterMateInventoryId) -> {
            LambdaUpdateWrapper<MateInventoryCxDetailLog> detailUpdateWrapper = new LambdaUpdateWrapper<>();
            detailUpdateWrapper.eq(MateInventoryCxDetailLog::getId, detailLogId);
            detailUpdateWrapper.set(MateInventoryCxDetailLog::getAfterMateInventoryId, afterMateInventoryId);
            mateInventoryCxDetailLogMapper.update(null, detailUpdateWrapper);
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteMateInventoryCxLog(Long mateInventoryCxLogId) {
        MateInventoryCxLogInfo mateInventoryCxLogInfo = mateInventoryCxLogMapper.getMateInventoryCxLogById(mateInventoryCxLogId);
        if (!mateInventoryCxLogInfo.getOrderStatus().equals(MateInventoryCxLogOrderStatusEnum.S1.getIntValue())) {
            throw new BusinessException(WarehouseRespCode.MATE_INVENTORY_CX_LOG_DELETE_STATUS_ERR);
        }
        LambdaUpdateWrapper<MateInventoryCxLog> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(MateInventoryCxLog::getId, mateInventoryCxLogId);
        updateWrapper.set(MateInventoryCxLog::getIsDeleted, true);
        mateInventoryCxLogMapper.update(null, updateWrapper);

        LambdaUpdateWrapper<MateInventoryCxDetailLog> detailUpdateWrapper = new LambdaUpdateWrapper<>();
        detailUpdateWrapper.eq(MateInventoryCxDetailLog::getOrderNo, mateInventoryCxLogInfo.getOrderNo());
        detailUpdateWrapper.set(MateInventoryCxDetailLog::getIsDeleted, true);
        mateInventoryCxDetailLogMapper.update(null, detailUpdateWrapper);
    }

    /**
     * 货品模式
     *
     * @param request
     * @return
     */
    @Override
    public Page<MateInventoryCxLogModeInfo> queryMateInventoryCxLogMode(MateInventoryCxLogModeQueryRequest request) {
        return mateInventoryCxLogMapper.queryMateInventoryCxLogMode(PageUtils.buildPage(request), request);
    }
}
